package com.wenx.v3gateway.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 健康检查控制器
 * 
 * @author v3-cloud
 */
@RestController
public class HealthController {

    @Autowired(required = false)
    private DiscoveryClient discoveryClient;
    
    @Autowired(required = false)
    private RouteLocator routeLocator;
    
    /**
     * 健康检查 - 检查网关和核心服务的可用性
     */
    @GetMapping("/health")
    public Mono<Map<String, Object>> health() {
        Map<String, Object> result = new HashMap<>();
        result.put("service", "v3-gateway");
        result.put("timestamp", LocalDateTime.now());
        
        if (discoveryClient == null) {
            result.put("status", "UP");
            result.put("message", "网关运行正常，未配置服务发现");
            return Mono.just(result);
        }
        
        List<String> allServices = discoveryClient.getServices();
        result.put("discoveredServices", allServices);
        
        // 检查核心业务服务
        List<String> coreServices = List.of("v3-auth", "v3-system", "v3-batch", "v3-storage", "v3-workflow");
        List<String> availableServices = coreServices.stream()
                .filter(service -> !discoveryClient.getInstances(service).isEmpty())
                .collect(Collectors.toList());
        
        result.put("coreServices", coreServices.size());
        result.put("availableServices", availableServices.size());
        result.put("availableServicesList", availableServices);
        
        // 简化状态判断
        if (availableServices.size() == coreServices.size()) {
            result.put("status", "UP");
            result.put("message", "所有核心服务已注册");
        } else if (availableServices.size() > 0) {
            result.put("status", "DEGRADED");
            result.put("message", String.format("部分核心服务不可用 (%d/%d)", 
                    availableServices.size(), coreServices.size()));
        } else {
            result.put("status", "DOWN");
            result.put("message", "核心服务均不可用");
        }
        
        return Mono.just(result);
    }
    
    /**
     * 路由信息
     */
    @GetMapping("/routes-info")
    public Mono<List<Map<String, Object>>> routesInfo() {
        if (routeLocator == null) {
            return Mono.just(List.of());
        }
        
        return routeLocator.getRoutes()
                .map(route -> {
                    Map<String, Object> routeInfo = new HashMap<>();
                    routeInfo.put("id", route.getId());
                    routeInfo.put("uri", route.getUri().toString());
                    
                    // 添加实例数量信息
                    String uri = route.getUri().toString();
                    if (uri.startsWith("lb://") && discoveryClient != null) {
                        String serviceName = uri.substring(5);
                        int instanceCount = discoveryClient.getInstances(serviceName).size();
                        routeInfo.put("instances", instanceCount);
                    }
                    
                    return routeInfo;
                })
                .collectList();
    }
    
    /**
     * 服务实例信息
     */
    @GetMapping("/services")
    public Mono<Map<String, Object>> services() {
        if (discoveryClient == null) {
            return Mono.just(Map.of("message", "服务发现未配置"));
        }
        
        Map<String, Object> result = new HashMap<>();
        Map<String, Integer> serviceInstances = new HashMap<>();
        
        discoveryClient.getServices().forEach(serviceName -> {
            int instanceCount = discoveryClient.getInstances(serviceName).size();
            serviceInstances.put(serviceName, instanceCount);
        });
        
        result.put("services", serviceInstances);
        result.put("timestamp", LocalDateTime.now());
        
        return Mono.just(result);
    }
} 